package com.ktgj.customer.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ktgj.common.core.annotation.Excel;
import com.ktgj.common.core.constant.BusinessTypeConstants;
import com.ktgj.common.core.constant.CustomerConstants;
import com.ktgj.common.core.domain.R;
import com.ktgj.common.core.enums.EmHelper;
import com.ktgj.common.core.utils.*;
import com.ktgj.common.core.utils.helper.CloneHelper;
import com.ktgj.common.log.enums.BusinessType;
import com.ktgj.common.redis.service.RedisService;
import com.ktgj.customer.common.CardConstant;
import com.ktgj.customer.domain.*;
import com.ktgj.customer.domain.dto.CalculationDTO;
import com.ktgj.customer.domain.dto.DiscountDescDTO;
import com.ktgj.customer.domain.vo.CalculationVO;
import com.ktgj.customer.mapper.*;
import com.ktgj.customer.service.*;
import com.ktgj.pay.api.RemotePayService;
import com.ktgj.pay.api.domain.PayTypeApi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Transactional
public class CardPurchaseServiceImpl implements ICardPurchaseService
{

    private static final Logger logger = LoggerFactory.getLogger(CardPurchaseServiceImpl.class);

    @Autowired
    private CardMapper cardMapper;
    @Autowired
    private BusinessOrderMapper businessOrderMapper;
    @Autowired
    private BusinessOrderSubMapper businessOrderSubMapper;
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private CustomerCardMapper customerCardMapper;
    @Autowired
    private EquityPackMapper equityPackMapper;
    @Autowired
    private RightdetailMapper rightdetailMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private ICardService cardService;
    @Autowired
    private ICustomerRightdetailService customerRightdetailService;
    @Autowired
    private IPointRecordService pointRecordService;
    @Autowired
    private IUtilServiceImpl iUtilService;
    @Autowired
    private IDepositBusinessService depositBusinessService;
    @Autowired
    private IPointRecordService recordService;
    @Autowired
    private RemotePayService payService;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private CustomerCardRecordMapper customerCardRecordMapper;
    @Autowired
    private ILoginService loginService;
    @Autowired
    private BusinessOrderAssistMapper businessOrderAssistMapper;
    @Autowired
    private IAssistProductService assistProductService;

    /**
     * 目前没有考虑未他人购卡的场景
     */
    //下单接口
    @Override
    public String buyCardOrder(Long customerId, Long id, Long creditsNum, Long couponId, BigDecimal usedMoney, BigDecimal couponMoney, BigDecimal usedDeposit, String businessType) throws Exception
    {
        BusinessOrder businessOrder = new BusinessOrder();
        BusinessOrderSub businessOrderSub = new BusinessOrderSub();
        Date date = DateUtils.getNowDate();
        Card card = new Card();
        EquityPack equityPack = new EquityPack();
        String orderSourceDesc;
        String orderType;
        if (businessType.equals(CustomerConstants.newCard.getValue()))
        {//开卡
            card = cardMapper.selectCardById(id);//获取到卡的信息
            businessOrder.setPrice(card.getPrice());//支付金额
            orderSourceDesc = "购买“" + card.getCardSectionName() + "”";
            orderType = CustomerConstants.newCard.getValue();
        } else if (businessType.equals(CustomerConstants.renewCard.getValue()))
        {//续费
            Long cardId = customerCardMapper.selectCardIdById(id);
            card = cardMapper.selectCardById(cardId);//获取到卡的信息
            businessOrder.setPrice(card.getPrice());//支付金额
            businessOrderSub.setCustomerCardId(CloneHelper.deepClone(id));
            id = cardId;
            orderSourceDesc = "续费“" + card.getCardSectionName() + "”";
            orderType = CustomerConstants.renewCard.getValue();
        } else
        {//权益包
            equityPack = equityPackMapper.selectEquityPackById(id);//获取到权益包的信息
            businessOrder.setPrice(equityPack.getPrice());//支付金额
            orderSourceDesc = "购买“" + equityPack.getEquitypackName() + "”";
            orderType = CustomerConstants.newPack.getValue();
        }
        //生成订单
        businessOrder.setBusinessType(businessType);//业务类型
        SnowflakeUtils snowflakeUtils = new SnowflakeUtils();
        businessOrder.setOrdernum(String.valueOf(snowflakeUtils.nextId()));//订单号
        businessOrder.setState(CustomerConstants.waitPay.getValue());//支付状态
        businessOrder.setUsedMoney(usedMoney);//实收金额
        businessOrder.setCreditsNum(creditsNum);//积分

        if (couponId != null)
            businessOrder.setUsedCouponId(couponId);//用户的抵扣卷id
        if (couponMoney != null)
            businessOrder.setUsedCoupon(couponMoney);//抵扣卷抵扣金额
        businessOrder.setUsedDeposit(usedDeposit);//预留款金额
        businessOrder.setCustomerId(customerId);//会员编号
        businessOrder.setCreateTime(date);//创建时间
        businessOrder.setCreateDemployeeId(1L);//创建员工
        businessOrder.setOrderState(CustomerConstants.waitPay.getValue());//订单状态
        businessOrderMapper.insertBusinessOrder(businessOrder);

        //生成子订单
        businessOrderSub.setOrderNum(businessOrder.getOrdernum());//订单号
        businessOrderSub.setOrderId(businessOrder.getOrderId());//订单主表id
        businessOrderSub.setCardId(id);//卡or权益包id
        if (businessType.equals(CustomerConstants.newCard.getValue()) || businessType.equals(CustomerConstants.renewCard.getValue()))
        {//开卡
            businessOrderSub.setCardName(card.getCardSectionName());//卡名称
            businessOrderSub.setCardPrice(card.getPrice());//卡售价
        } else
        {//权益包
            businessOrderSub.setCardName(equityPack.getEquitypackName());//权益包名称
            businessOrderSub.setCardPrice(equityPack.getPrice());//权益包售价
        }
        businessOrderSub.setRenewCardStatus(businessType);//开卡续费状态
        businessOrderSubMapper.insertBusinessOrderSub(businessOrderSub);
        List<BusinessOrderSub> list = new ArrayList<>();
        list.add(businessOrderSub);
        businessOrder.setBusinessOrderSubs(list);

        try
        {
            pointRecordService.spend(customerId, creditsNum, orderType, businessOrder.getOrderId(), orderSourceDesc, couponId, 1L);//会员id、要扣减的积分、订单类型、订单id、订单描述（客户端展示使用），例如机票 显示航程+航班号、使用优惠卷的id、预留款、操作员工id
        } catch (Exception e)
        {
            throw new Exception(e.getMessage());
        }


        //存入redis，查找待支付订单时用
        redisService.setCacheObject("order" + customerId + "u" + businessOrder.getOrdernum(), JSON.toJSONString(businessOrder), 60 * 30l, TimeUnit.SECONDS);//存入redis,有效期30分钟
        return businessOrder.getOrdernum();
    }

    /**
     * 目前没有考虑未他人购卡的场景
     */
    //预支付接口
    @Override
    public Map<String, Object> queryOrderInfoByNum(String orderNum)
    {
        BusinessOrder businessOrder = businessOrderMapper.selectBusinessOrderByNum(orderNum);
        BusinessOrderSub businessOrderSub = businessOrder.getBusinessOrderSubs().get(0);
        Map<String, Object> subMap = new HashMap<>();
        Customer customer = customerMapper.selectCustomerById(businessOrder.getCustomerId());
        if (businessOrder.getBusinessType().equals(CustomerConstants.newCard.getValue()) || businessOrder.getBusinessType().equals(CustomerConstants.renewCard.getValue()))
        {
            Card card = cardMapper.selectCardById(businessOrderSub.getCardId());
            if (businessOrder.getBusinessType().equals(CustomerConstants.newCard.getValue()))
                subMap.put("cardName", "购买" + card.getCardSectionName());
            else
                subMap.put("cardName", "续费" + card.getCardSectionName());
            subMap.put("customerName", customer.getCustomerName());
            subMap.put("cardDetails", card.getCardDetails());
        } else
        {
            EquityPack equityPack = equityPackMapper.selectEquityPackById(businessOrderSub.getCardId());//获取到权益包的信息
            subMap.put("cardName", "购买" + equityPack.getEquitypackName());
            subMap.put("customerName", customer.getCustomerName());
            subMap.put("cardDetails", equityPack.getEquitypackDetails());
        }
        Map<String, Object> map = new HashMap<>();
        Long expireTime = redisService.redisTemplate.getExpire("order" + businessOrder.getCustomerId() + "u" + businessOrder.getOrdernum());
        if (expireTime != null && expireTime > 0)
            map.put("expireTime", expireTime);
        else
            map.put("expireTime", "订单已超时！");
        map.put("orderSub", subMap);
        map.put("usedMoney", businessOrder.getPrice());

        List<PayTypeApi> payTypes = payService.queryPayType("cardAPPPurchase");
        map.put("payTypes", payTypes);

        return map;
    }

    //微信小程序支付
    @Override
    public Map<String, Object> wechatPay(String openId, String orderNumber, HttpServletRequest request, BigDecimal amount, String type) throws Exception
    {
        BusinessOrder businessOrder = businessOrderMapper.selectBusinessOrderByNum(orderNumber);

        Employee loginEmployee = loginService.getLoginEmployee(request);
        if (loginEmployee != null)
        {
            throw new Exception("登录已过期");
        }

        if (amount.compareTo(new BigDecimal(0)) > 0)
        {
            businessOrder.setPrice(businessOrder.getPrice().subtract(amount));

            businessOrder.setAmount(amount);
            int i = businessOrderMapper.updateBusinessOrder(businessOrder);
            if (i <= 0)
            {
                throw new Exception("修改订单预留款失败");
            }

            DepositBusiness depositBusiness = new DepositBusiness();
            depositBusiness.setRemark("会员卡微信小程序支付");
            depositBusiness.setState("false");
            depositBusiness.setBusinessType(EmHelper.businessType.Customer.getValue());
            depositBusiness.setOperatorId(loginEmployee.getEmployeeId());
            depositBusiness.setOrdersourceid(type);
            depositBusiness.setCustomerId(businessOrder.getCustomerId());
            depositBusiness.setDetailamount(amount);
            depositBusiness.setChangetype(2l);
            depositBusiness.setLockState("false");
            depositBusiness.setOrderId(Long.valueOf(orderNumber));
            depositBusiness.setDrawState("false");
            Long aLong = depositBusinessService.insertDepositBusiness(depositBusiness);
            if (aLong <= 0)
            {
                throw new Exception("添加预留款记录失败");
            }

            boolean coinAudit = depositBusinessService.goldCoinAudit(loginEmployee.getEmployeeId(), aLong, "会员卡微信小程序支付");
            if (!coinAudit)
            {
                throw new Exception("审核失败，请进行人工审核");
            }
        }

        String notifyUrl = "/customer/callback/wechatPayCallback";
        R<Map> wechatJSAPIPayParam = payService.getWechatJSAPIPayParam(openId, businessOrder.getPrice(), orderNumber, notifyUrl);
        if (wechatJSAPIPayParam.getCode() == 200)
        {
            return wechatJSAPIPayParam.getData();
        }
        return null;
    }

    @Override
    public void updateCardInvalid()
    {
        customerCardMapper.updateCardInvalid();
    }

    /**
     * 目前没有考虑未他人购卡的场景
     */
    //支付完成后回调接口
    @Override
    public void orderResult(boolean bool, String orderNum, String partyPayNum) throws ParseException
    {
        Date date = DateUtils.getNowDate();
        BusinessOrder businessOrder = businessOrderMapper.selectBusinessOrderByNum(orderNum);
        if (bool)
        {//回调判断支付成功
            businessOrder.setState(CustomerConstants.payd.getValue());
            businessOrder.setOrderState(CustomerConstants.payd.getValue());
            businessOrder.setPartyPayNum(partyPayNum);
            businessOrderMapper.updateBusinessOrder(businessOrder);/** 修改订单状态 */

            redisService.deleteObject("order" + businessOrder.getCustomerId() + "u" + orderNum);//把redis中记录的待支付订单删除掉

            //添加积分
            BusinessOrderSub businessOrderSub = businessOrder.getBusinessOrderSubs().get(0);
            if (businessOrder.getBusinessType().equals(CustomerConstants.newCard.getValue()) || businessOrder.getBusinessType().equals(CustomerConstants.renewCard.getValue()))
            {

                Card card = cardService.selectCardAndHaveRightdetailsById(businessOrderSub.getCardId());
                CustomerCard customerCard = new CustomerCard();
                if (businessOrder.getBusinessType().equals(CustomerConstants.newCard.getValue()))
                {//购卡
                    //创建新的会员卡
                    customerCard.setCardId(card.getCardId());//卡id
                    customerCard.setCardCode(getCardCode(card));//卡号
                    customerCard.setCustomerId(businessOrder.getCustomerId());//会员id
                    customerCard.setCreateEmployeeId(businessOrder.getCreateDemployeeId());//创建人
                    customerCard.setCreateTime(date);//创建时间
                    customerCard.setValidDate(date);//生效日期
                    customerCard.setInvalidDate(DateUtils.addDays(date, card.getValidDate().intValue()));//失效日期
                    customerCard.setCardStatus(CustomerConstants.valid.getValue());//卡状态
                    customerCard.setCarddmansId(businessOrder.getCreateDemployeeId());//售卡人
                    customerCard.setSalePrice(card.getPrice());//售卡价格
                    customerCard.setOrderSubId(businessOrderSub.getOrderSubId());//子订单id
                    customerCard.setSaleDateAct(businessOrder.getCreateTime());//实际售卡日期

                    customerCardMapper.insertCustomerCard(customerCard);/** 新开会员卡*/

                    businessOrderSub.setCustomerCardId(customerCard.getCustomerCardId());//回写子订单
                } else
                {//续费
                    customerCard = customerCardMapper.selectCustomerCardById(businessOrderSub.getCustomerCardId());
                    customerCard.setBusinessDate(date);
                    customerCard.setInvalidDate(DateUtils.addDays(date, card.getValidDate().intValue()));
                    customerCard.setCardStatus(CustomerConstants.valid.getValue());//卡状态
                    customerCard.setOrderSubId(businessOrderSub.getOrderSubId());//子订单id
                    customerCardMapper.updateCustomerCard(customerCard);
                }
                businessOrderSub.setNewCardTime(date);
                businessOrderSub.setInvalidTime(DateUtils.addDays(date, card.getValidDate().intValue()));
                businessOrderSub.setWhetherRefund(CustomerConstants.no.getValue());
                businessOrderSubMapper.updateBusinessOrderSub(businessOrderSub);/** 回写子订单 */

                if (card.getLstRightDetail() != null && card.getLstRightDetail().size() != 0)
                {
                    /**新增会员权益*/
                    customerRightdetailService.addCustomerRightdetail(card.getLstRightDetail(), businessOrder.getCustomerId(), date, DateUtils.addDays(date, card.getValidDate().intValue()),
                            businessOrder.getCreateDemployeeId(), CustomerConstants.rightSourceCard.getValue(), businessOrderSub.getCustomerCardId(), businessOrderSub.getOrderSubId(), customerCard.getCardCode(), businessOrder.getPayType(), businessOrder.getOrdernum());
                }
            } else
            {//权益包
                //(权益集合， 会员id， 生效时间， 到期时间， 员工id， 权益来源（卡、权益包）， 会员卡id， 子订单id)
                List<Rightdetail> rightdetails = rightdetailMapper.selectrightdetailbyPackId(businessOrderSub.getCardId());
                customerRightdetailService.addCustomerRightdetail(rightdetails, businessOrder.getCustomerId(), date, DateUtils.addYears(date, 1),
                        businessOrder.getCreateDemployeeId(), CustomerConstants.rightSourcePack.getValue(), businessOrderSub.getCardId(), businessOrderSub.getOrderSubId(), null, businessOrder.getPayType(), businessOrder.getOrdernum());
            }
            pointRecordService.addPointRecord(businessOrder.getPrice(), "购卡", 1L, businessOrder.getCustomerId(), CustomerConstants.newCard.getValue(), businessOrder.getOrderId(), "");
        } else
        {//回调判断支付失败
            businessOrder.setState(CustomerConstants.failPay.getValue());
            businessOrderMapper.updateBusinessOrder(businessOrder);//修改订单支付状态
        }
    }

    //查询待支付订单
    @Override
    public List<BusinessOrder> getWaitPayOrder(Long customerId)
    {
        List<BusinessOrder> businessOrders = new ArrayList<>();
        Collection<String> keys = redisService.keys("order" + customerId + "u*");
        for (String key : keys)
        {
            String orderJson = redisService.getCacheObject(key);
            BusinessOrder businessOrder = JSONObject.parseObject(orderJson, BusinessOrder.class);//根据key逐个取出
            businessOrders.add(businessOrder);
        }
        return businessOrders;
    }


    //生成卡号
    @Override
    public String getCardCode(Card card)
    {
        /**查询出最后一张卡的卡号*/
        String lastCustomerCardCode = customerCardMapper.selectLastCustomerCardCodeByCardId(card.getCardId());

        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(card.getPrefix());//先把前缀加上

        String Value = "";//中间值
        if (lastCustomerCardCode == null || lastCustomerCardCode.equals(""))
        {//生成第一个卡号
            Value = card.getMidStartValue().toString();
        } else
        {//不是第一次生成
            String lastCode = "";
            /**把中间值截取出来*/
            if (card.getEndType().equals(CustomerConstants.fixed.getValue()))
                lastCode = lastCustomerCardCode.substring(card.getPrefix().length(), lastCustomerCardCode.length() - card.getEndValue().toString().length());
            else
                lastCode = lastCustomerCardCode.substring(card.getPrefix().length());
            /**中间值++*/
            Integer code = Integer.valueOf(lastCode);
            code = code + 1;
            Value = code.toString();
        }
        /**补全中间值长度*/
        for (int i = Value.length(); i < card.getMidDigit(); i++)
        {
            stringBuffer.append('0');
        }
        stringBuffer.append(Value);//把中间值加上
        if (card.getEndType().equals(CustomerConstants.fixed.getValue()))
            stringBuffer.append(card.getEndValue());//如果有后缀，把后缀加上
        return stringBuffer.toString();
    }


    /**
     * 以上代码为照着老版本app写的接口，
     * 以下代码为照着新出的设计图，根据老版本的代码改变而来
     *
     *
     * @autoor 张金龙
     * @version 2.0
     */

    /**
     * app购卡下单接口
     *
     * @param customerId 用户id
     * @param id         购买的卡id
     * @param usePoint   是否使用积分
     * @param couponId   是否使用优惠券
     * @param usedMoney  前端通过计算接口算出来的金额，传进来再算一边做验证
     *                   UtilController.calculation(CalculationVO calculationVO)
     * @param useDeposit 是否使用金币（预留款）
     * @param years      购买年限
     * @return
     */
    @Override
    public String appPuyCardOrder(Long customerId, Long id, boolean usePoint, Long couponId, BigDecimal usedMoney, boolean useDeposit, String years, Long customerId1, List<Integer> product) throws Exception
    {
//        int count = businessOrderSubMapper.queryCardCount(customerId1, id);//todo 买了几张 order ****
//        if (count >= 3)
//            return "该卡购买数量已达上限，暂且不能购买，请等待已有的卡片到期再次购买";

        Card card = cardMapper.selectCardById(id);//获取到卡的信息
        String orderSourceDesc = "购买“" + card.getCardSectionName() + "”";
        String orderType = CustomerConstants.newCard.getValue();

        //进行价格计算
        CalculationVO calculationVO = new CalculationVO();
        List<BigDecimal> prices = new ArrayList<>();
        prices.add(years.equals("one") ? card.getPrice() : card.getContinuousPrice());
        calculationVO.setPrices(prices);
        calculationVO.setAmount(years.equals("one") ? 1 : 2);
        calculationVO.setCouponId(couponId);
        BigDecimal usedDeposit = depositBusinessService.queyUserDepositBusiness(customerId);
        calculationVO.setDepositAmount(usedDeposit);
        calculationVO.setUseDeposit(useDeposit);
        calculationVO.setUsePoint(usePoint);
        try
        {
            calculationVO.setPointAmount(recordService.queryUserCreditsNum(customerId).intValue());
        } catch (Exception e)
        {
            calculationVO.setPointAmount(0);
        }

        CalculationDTO calculationDTO = iUtilService.calculation(calculationVO);

        if (usedMoney.compareTo(calculationDTO.getPrice()) != 0)
        {
            return "下单失败，传入的结算价格不符合";
        }

        Date date = DateUtils.getNowDate();

        //生成订单
        BusinessOrder businessOrder = new BusinessOrder();

//        businessOrder.setPrice(calculationDTO.getPrice());//
        //todo 测试订单金额写死
        businessOrder.setPrice(new BigDecimal(0.1));//支付金额
        businessOrder.setBusinessType(CustomerConstants.newCard.getValue());//业务类型
        SnowFlake snowFlake = new SnowFlake(28, 28);
        businessOrder.setOrdernum(String.valueOf(snowFlake.nextId()));//订单号
        businessOrder.setState(CustomerConstants.waitPay.getValue());//支付状态
        businessOrder.setUsedMoney(calculationDTO.getActualPriceDetailed().getOriginalPrice());//实收金额
        businessOrder.setCustomerId(customerId);//会员编号
        businessOrder.setCreateTime(date);//创建时间
        businessOrder.setCreateDemployeeId(1L);//创建员工
        businessOrder.setOrderState(CustomerConstants.waitPay.getValue());//订单状态
        businessOrder.setSourceway(6L);

        if (calculationDTO.getUsePointDesc().equals("积分不足")) {
            businessOrder.setUsedCredits(new BigDecimal(0));
            businessOrder.setCreditsNum(0L);
        }


        //从计算接口返回的对象中，取计算的价格结果
        if (calculationDTO.getActualPriceDetailed().getDiscountDesc().size() > 0) {
            for (DiscountDescDTO item : calculationDTO.getActualPriceDetailed().getDiscountDesc()) {

                if (item.getDesc().equals("优惠券")) {
                    if (couponId != null) {
                        businessOrder.setUsedCouponId(couponId);//用户的抵扣卷id
                        businessOrder.setUsedCoupon(item.getPrice());//抵扣卷抵扣金额

                    }
                }
                if (item.getDesc().equals("积分")) {
                    if (usePoint) {
                        businessOrder.setUsedCredits(item.getPrice());//积分抵现
                        BigDecimal multiply = item.getPrice().multiply(new BigDecimal(3000));
                        businessOrder.setCreditsNum(multiply.longValue());
                    } else {
                        businessOrder.setUsedCredits(new BigDecimal(0));
                        businessOrder.setCreditsNum(0L);
                    }
                }

                if (item.getDesc().equals("金币")) {
                    if (useDeposit)
                        businessOrder.setUsedDeposit(item.getPrice());//预留款金额
                }

            }
        } else {
            businessOrder.setUsedCoupon(BigDecimal.valueOf(0));//抵扣卷抵扣金额
            businessOrder.setUsedCredits(new BigDecimal(0));
            businessOrder.setCreditsNum(0L);
            businessOrder.setUsedDeposit(BigDecimal.valueOf(0));//预留款金额
        }

        businessOrderMapper.insertBusinessOrder(businessOrder);

        if (product.size() > 0) {
            for (Integer integer : product) {
                AssistProduct assistProduct = assistProductService.queryAssistProduct(Long.valueOf(integer));
                BusinessOrderAssist businessOrderAssist = new BusinessOrderAssist();
                businessOrderAssist.setName(assistProduct.getName());
                businessOrderAssist.setPrice(assistProduct.getSalePrice());
                businessOrderAssist.setAssistProductId(Long.valueOf(integer));
                businessOrderAssist.setStatus("wait");
                businessOrderAssist.setCreateTime(new Date());
                businessOrderAssist.setOrdernum(businessOrder.getOrdernum());
                businessOrderAssist.setInsType(assistProduct.getProductType());
                businessOrderAssistMapper.insertBusinessOrderAssist(businessOrderAssist);
            }
        }

        CustomerMessage customerMessage = new CustomerMessage();
        customerMessage.setBusinessType(BusinessTypeConstants.customer.getValue());
        customerMessage.setCreateTime(DateUtils.getNowDate());
        customerMessage.setIsRead("unread");
        customerMessage.setCustomerId(customerId);
        customerMessage.setMessageContent(DateUtils.getNowDate() + "您购买了一张空铁管家" + card.getCardSectionName());
        customerService.addCustomerMessage(customerMessage);
        //生成子订单
        BusinessOrderSub businessOrderSub = new BusinessOrderSub();
        businessOrderSub.setOrderNum(businessOrder.getOrdernum());//订单号
        businessOrderSub.setOrderId(businessOrder.getOrderId());//订单主表id
        businessOrderSub.setCardId(id);//卡id
        businessOrderSub.setCardName(card.getCardSectionName());//卡名称
        businessOrderSub.setCardPrice(years.equals("one") ? card.getPrice() : card.getContinuousPrice());//卡售价
        businessOrderSub.setRenewCardStatus(CustomerConstants.newCard.getValue());//开卡续费状态
        businessOrderSub.setNewCustomerid(customerId1);//卡归属人会员编号
        businessOrderSub.setMyselfBuycard(customerId.equals(customerId1) ? 0L : 1L);//是否本人购卡
        businessOrderSubMapper.insertBusinessOrderSub(businessOrderSub);
        List<BusinessOrderSub> list = new ArrayList<>();
        list.add(businessOrderSub);

        if (years.equals("two"))
        {//如果是连续包年购卡，需要一次买两年，生成两笔子订单
            BusinessOrderSub businessOrderSubTwo = new BusinessOrderSub();
            businessOrderSubTwo.setOrderNum(String.valueOf(snowFlake.nextId()));//订单号
            businessOrderSubTwo.setOrderId(businessOrder.getOrderId());//订单主表id
            businessOrderSubTwo.setCardId(id);//卡id
            businessOrderSubTwo.setCardName(card.getCardSectionName());//卡名称
            businessOrderSubTwo.setCardPrice(card.getContinuousPrice());//卡售价
            businessOrderSubTwo.setRenewCardStatus(CustomerConstants.newContinuousCard.getValue());//开卡续费状态
            businessOrderSubTwo.setNewCustomerid(customerId1);//卡归属人会员编号
            businessOrderSubTwo.setMyselfBuycard(customerId.equals(customerId1) ? 0L : 1L);//是否本人购卡
            businessOrderSubMapper.insertBusinessOrderSub(businessOrderSubTwo);
            list.add(businessOrderSubTwo);
        }


        businessOrder.setBusinessOrderSubs(list);

        //花费资产
        try
        {
            pointRecordService.spend(customerId, businessOrder.getCreditsNum(), orderType, businessOrder.getOrderId(), orderSourceDesc, couponId, 1L);//会员id、要扣减的积分、订单类型、订单id、订单描述（客户端展示使用），例如机票 显示航程+航班号、使用优惠卷的id、预留款、操作员工id
        } catch (Exception e)
        {
            logger.error(e.getMessage());
            throw new Exception(e.getMessage());
        }

        //存入redis，查找待支付订单时用
        redisService.setCacheObject("order" + customerId + "u" + businessOrder.getOrdernum(), JSON.toJSONString(businessOrder), 60 * 30l, TimeUnit.SECONDS);//存入redis,有效期30分钟
        return businessOrder.getOrdernum();
    }


    @Override
    public String cardOrderResult(boolean bool, String orderNum, String partyPayNum, String payType)
    {
        BusinessOrder businessOrder = businessOrderMapper.selectBusinessOrderByNum(orderNum);
        try
        {
            if (bool)
            {//回调判断支付成功
                businessOrder.setState(CustomerConstants.payd.getValue());
                businessOrder.setOrderState(CustomerConstants.payd.getValue());
                businessOrder.setPartyPayNum(partyPayNum);
                businessOrder.setPayType(payType);
                businessOrderMapper.updateBusinessOrder(businessOrder);/** 修改订单状态 */

                redisService.deleteObject("order" + businessOrder.getCustomerId() + "u" + orderNum);//把redis中记录的待支付订单删除掉
                for (BusinessOrderSub item : businessOrder.getBusinessOrderSubs())
                {
                    CustomerCardRecord queryCustomerCard = new CustomerCardRecord();
                    Card card = cardService.selectCardAndHaveRightdetailsById(item.getCardId());
                    if (item.getRenewCardStatus().equals(CustomerConstants.newCard.getValue()))
                    {
                        //如果用户选择的是开两年的卡，分两种情况，立即执行，当前会员没有本类型的卡，则一张立即执行，另外一张未执行，如果会员有同类型的卡，则取最后一张的时间，添加两张未执行
                        if (businessOrder.getYears().equals(CustomerConstants.twoYear.getValue()))
                        {
                            List<CustomerCard> lstCustomerCard = customerCardMapper.queryCardIdByCustomerId(item.getNewCustomerid());
                            CustomerCard customerCard = lstCustomerCard.stream().filter(x -> x.getCardId().equals(card.getCardId())).findFirst().orElse(null);
                            //如果会员有这张卡，开立即执行就是并行
                            if (customerCard != null)
                            {
                                createCard(item, card, businessOrder);
                                createCard(item, card, businessOrder);
                                queryCustomerCard.setCardCode(businessOrder.getCardCode());
                            } else
                            {
                                createCard(item, card, businessOrder);
                                queryCustomerCard = new CustomerCardRecord();
                                fillCustomerCardRecord(queryCustomerCard, card, businessOrder , item);
                                queryCustomerCard.setCardCode(businessOrder.getCardCode());
                                queryCustomerCard.setExecutedate(DateCalcUtils.addDay(DateUtils.getNowDate(), 2));
                                customerCardRecordMapper.insertCustomerCardRecord(queryCustomerCard);
                            }
                        } else
                        {
                            createCard(item, card, businessOrder);
                        }
                    }
                    if (item.getRenewCardStatus().equals(CustomerConstants.newContinuousCard.getValue()))
                    {
                        queryCustomerCard = new CustomerCardRecord();
                        queryCustomerCard.setCustormerId(businessOrder.getCustomerId());
                        queryCustomerCard.setCardId(card.getCardId());
                        List<CustomerCardRecord> lstCustomerRecord = customerCardRecordMapper.selectCustomerCardRecordList(queryCustomerCard);
                        lstCustomerRecord = lstCustomerRecord.stream().sorted(Comparator.comparing(CustomerCardRecord::getExecutedate).reversed()).collect(Collectors.toList());
                        //todo 续费记录表的操作
                        CustomerCardRecord customerCardRecord = new CustomerCardRecord();
                        fillCustomerCardRecord(customerCardRecord, card, businessOrder , item);
                        if (businessOrder.getYears().equals(CustomerConstants.twoYear.getValue()))
                        {
                            if (lstCustomerRecord.size() == 0)
                            {
                                customerCardRecord.setExecutedate(DateCalcUtils.addDay(DateUtils.getNowDate(), 1));
                                CustomerCardRecord cardRecord2 = new CustomerCardRecord();
                                BeanUtils.copyProperties(customerCardRecord, cardRecord2);
                                cardRecord2.setExecutedate(DateCalcUtils.addYear(customerCardRecord.getExecutedate(), 1));
                                cardRecord2.setExecutedate(DateCalcUtils.addDay(cardRecord2.getExecutedate(), 1));
                                customerCardRecordMapper.insertCustomerCardRecord(cardRecord2);
                            } else
                            {
                                //直接延期执行两年的情况，先获取当前
                                CustomerCardRecord tmpCardRecord = lstCustomerRecord.get(0);
                                customerCardRecord.setExecutedate(DateCalcUtils.addYear(tmpCardRecord.getExecutedate(), 1));
                                customerCardRecord.setExecutedate(DateCalcUtils.addDay(customerCardRecord.getExecutedate(), 1));
                                CustomerCardRecord cardRecord2 = new CustomerCardRecord();
                                BeanUtils.copyProperties(customerCardRecord, cardRecord2);
                                cardRecord2.setExecutedate(DateCalcUtils.addYear(customerCardRecord.getExecutedate(), 1));
                                cardRecord2.setExecutedate(DateCalcUtils.addDay(cardRecord2.getExecutedate(), 1));
                                customerCardRecordMapper.insertCustomerCardRecord(cardRecord2);
                            }
                            customerCardRecordMapper.insertCustomerCardRecord(customerCardRecord);
                        }else {
                            if (lstCustomerRecord.size() == 0)
                            {
                                customerCardRecord.setExecutedate(DateCalcUtils.addDay(DateUtils.getNowDate(), 1));
                            } else
                            {
                                CustomerCardRecord cardRecord = lstCustomerRecord.get(0);
                                customerCardRecord.setExecutedate(DateCalcUtils.addYear(cardRecord.getExecutedate(), 1));
                                customerCardRecord.setExecutedate(DateCalcUtils.addDay(customerCardRecord.getExecutedate(), 1));
                            }
                            customerCardRecordMapper.insertCustomerCardRecord(customerCardRecord);
                        }
                    }
                    businessOrder.setCardCode(queryCustomerCard.getCardCode());
                }
                //添加积分
                pointRecordService.addPointRecord(businessOrder.getPrice(), "购卡", 1L, businessOrder.getCustomerId(), CustomerConstants.newCard.getValue(), businessOrder.getOrderId(), "");
            } else
            {//回调判断支付失败
                businessOrder.setState(CustomerConstants.failPay.getValue());
                businessOrderMapper.updateBusinessOrder(businessOrder);//修改订单支付状态
            }
        }catch (Exception e)
        {
            logger.error(e.getMessage());
        }
        return businessOrder.getCardCode();
    }

    public void fillCustomerCardRecord(CustomerCardRecord customerCardRecord, Card card, BusinessOrder businessOrder, BusinessOrderSub item)
    {
        Date date = new Date();
        customerCardRecord.setCardCode(businessOrder.getCardCode());
        customerCardRecord.setRenewPrice(card.getPrice());
        customerCardRecord.setCardId(item.getCardId());
        customerCardRecord.setCustormerId(item.getNewCustomerid());
        customerCardRecord.setOperadate(date);
        customerCardRecord.setOperamanid(businessOrder.getCreateDemployeeId());
        customerCardRecord.setIssyn(CustomerConstants.unexecuted.getValue());
        customerCardRecord.setNewguaranteeNo(businessOrder.getOrdernum());
        customerCardRecord.setExecutedate(item.getInvalidTime());
        customerCardRecord.setCardsolddeptid(businessOrder.getEmployeeDeptid());
        customerCardRecord.setCardsoldemployeeid(businessOrder.getEmployeeId());
        customerCardRecord.setOrderId(businessOrder.getOrderId());
    }

    @Override
    public boolean cardInvalid(List<CustomerCard> invalidCards)
    {
        try
        {
            customerContinue:
            //快过期卡的列表
            for (CustomerCard invalidCard : invalidCards)
            {
                List<BusinessOrder> list = businessOrderMapper.selectBusinessOrderByRecord(invalidCard.getCustomerId(), invalidCard.getCardId());//todo 这个人有没有待开的卡 order ****
                int no = 0;
                for (int i = 0; list.size() > i; i++)
                {
                    BusinessOrder businessOrder = list.get(i);
                    for (BusinessOrderSub item : businessOrder.getBusinessOrderSubs())
                    {
                        if (item.getRenewCardStatus().equals(CustomerConstants.newCard.getValue()))
                        {//到期开卡
                            Card card = cardService.selectCardAndHaveRightdetailsById(item.getCardId());
                            createCard(item, card, businessOrder);//开卡
                            invalidCard.setCardStatus(CustomerConstants.invalid.getValue());
                            customerCardMapper.updateCustomerCard(invalidCard);
                            continue customerContinue;
                        } else if (item.getRenewCardStatus().equals(CustomerConstants.newContinuousCard.getValue()) && item.getSame().equals("false"))
                        {
                            Card card = cardService.selectCardAndHaveRightdetailsById(item.getCardId());
                            CustomerCardRecord tmpCardRecord = new CustomerCardRecord();
                            tmpCardRecord.setOrderId(businessOrder.getOrderId());
                            List<CustomerCardRecord> lstCustomerCardRecord = customerCardRecordMapper.selectCustomerCardRecordList(tmpCardRecord);
                            if (lstCustomerCardRecord.size()>businessOrder.getBusinessOrderSubs().size())
                            {
                                createCard(item, card, businessOrder);//开卡
                                createCard(item, card, businessOrder);//开两张卡
                                for (CustomerCardRecord customerCardRecord :lstCustomerCardRecord)
                                {
                                    customerCardRecord.setIssyn(CustomerConstants.executed.getValue());
                                    customerCardRecordMapper.updateCustomerCardRecord(customerCardRecord);
                                }
                                continue customerContinue;
                            }else {
                                createCard(item, card, businessOrder);//开卡
                                continue customerContinue;
                            }
                        } else if (item.getRenewCardStatus().equals(CustomerConstants.newContinuousCard.getValue()) && no > 0)
                        {//连续包年
                            Card card = cardService.selectCardAndHaveRightdetailsById(item.getCardId());
                            createCard(item, card, businessOrder);
                            invalidCard.setCardStatus(CustomerConstants.invalid.getValue());
                            customerCardMapper.updateCustomerCard(invalidCard);

                            //连续包年后续操作
                            //生成订单
                            BusinessOrder businessOrder2 = new BusinessOrder();
//                      businessOrder2.setPrice(calculationDTO.getPrice());//支付金额
                            //todo 测试订单金额写死
                            businessOrder2.setPrice(new BigDecimal(0.01));//支付金额
                            businessOrder2.setBusinessType(CustomerConstants.newCard.getValue());//业务类型
                            SnowflakeUtils snowflakeUtils = new SnowflakeUtils();
                            businessOrder2.setOrdernum(String.valueOf(snowflakeUtils.nextId()));//订单号
                            businessOrder2.setState(CustomerConstants.waitPay.getValue());//支付状态
                            businessOrder2.setUsedMoney(businessOrder.getUsedMoney());//实收金额 //todo 我不确定我写的这行代码方法的入参正确，待测试
                            businessOrder2.setCustomerId(businessOrder.getCustomerId());//会员编号
                            businessOrder2.setCreateTime(DateUtils.getNowDate());//创建时间
                            businessOrder2.setCreateDemployeeId(1L);//创建员工
                            businessOrder2.setOrderState(CustomerConstants.waitPay.getValue());//订单状态
                            businessOrder2.setSourceway(6L);
                            businessOrder2.setUsedCoupon(new BigDecimal(0));//抵扣卷抵扣金额
                            businessOrder2.setUsedCredits(new BigDecimal(0));
                            businessOrder2.setUsedDeposit(new BigDecimal(0));//预留款金额
                            businessOrderMapper.insertBusinessOrder(businessOrder2);
                            CustomerMessage customerMessage = new CustomerMessage();
                            customerMessage.setBusinessType(BusinessTypeConstants.customer.getValue());
                            customerMessage.setCreateTime(DateUtils.getNowDate());
                            customerMessage.setIsRead("unread");
                            customerMessage.setCustomerId(businessOrder.getCustomerId());
                            customerMessage.setMessageContent(DateUtils.getNowDate() + "您连续包年自动扣款购买了一张空铁管家" + card.getCardSectionName());
                            customerService.addCustomerMessage(customerMessage);
                            //生成子订单
                            BusinessOrderSub businessOrderSub = new BusinessOrderSub();
                            businessOrderSub.setOrderNum(businessOrder2.getOrdernum());//订单号
                            businessOrderSub.setOrderId(businessOrder2.getOrderId());//订单主表id
                            businessOrderSub.setCardId(item.getCardId());//卡id
                            businessOrderSub.setCardName(card.getCardSectionName());//卡名称
                            businessOrderSub.setCardPrice(card.getContinuousPrice());//卡售价
                            businessOrderSub.setRenewCardStatus(CustomerConstants.newContinuousCard.getValue());//开卡续费状态
                            businessOrderSub.setNewCustomerid(item.getNewCustomerid());//卡归属人会员编号
                            businessOrderSub.setMyselfBuycard(businessOrder2.getCustomerId().equals(item.getNewCustomerid()) ? 0L : 1L);//是否本人购卡
                            businessOrderSubMapper.insertBusinessOrderSub(businessOrderSub);
                            //todo 自动扣款 -- 付款后的回调（更改订单状态）


                            continue customerContinue;
                        } else if (item.getRenewCardStatus().equals(CustomerConstants.newContinuousCard.getValue()) && i < list.size() - 1)
                        {
                            no++;
                        } else if (i == list.size() - 1)
                        {
                            i = 0;
                        }

                    }
                }
            }
            return true;
        } catch (Exception e)
        {
            logger.error(e.getMessage());
            return false;
        }
    }

    //会员开卡并且添加会员资产
    public void createCard(BusinessOrderSub item, Card card, BusinessOrder businessOrder)
    {
        Date date = DateUtils.getNowDate();

        CustomerCard customerCard = new CustomerCard();
        //创建新的会员卡
        customerCard.setCardId(card.getCardId());//卡id
        customerCard.setCardCode(getCardCode(card));//卡号
        customerCard.setCustomerId(item.getNewCustomerid());//会员id
        customerCard.setCreateEmployeeId(businessOrder.getCreateDemployeeId());//创建人
        customerCard.setCreateTime(date);//创建时间
        customerCard.setValidDate(date);//生效日期
        customerCard.setInvalidDate(DateUtils.addDays(date, card.getValidDate().intValue()));//失效日期
        customerCard.setCardStatus(CustomerConstants.valid.getValue());//卡状态
        customerCard.setCarddmansId(businessOrder.getCreateDemployeeId());//售卡人
        customerCard.setSalePrice(card.getPrice());//售卡价格
        customerCard.setOrderSubId(item.getOrderSubId());//子订单id
        customerCard.setSaleDateAct(businessOrder.getCreateTime());//实际售卡日期

        customerCardMapper.insertCustomerCard(customerCard);/** 新开会员卡*/

        item.setCustomerCardId(customerCard.getCustomerCardId());//回写子订单
        item.setNewCardTime(date);
        item.setInvalidTime(DateUtils.addDays(date, card.getValidDate().intValue()));
        item.setWhetherRefund(CustomerConstants.no.getValue());
        businessOrderSubMapper.updateBusinessOrderSub(item);/** 回写子订单 */
        businessOrder.setCardCode(customerCard.getCardCode());
        if (card.getLstRightDetail() != null && card.getLstRightDetail().size() != 0)
        {
            /**新增会员权益*/
            customerRightdetailService.addCustomerRightdetail(card.getLstRightDetail(), businessOrder.getCustomerId(), date, DateUtils.addDays(date, card.getValidDate().intValue()),
                    businessOrder.getCreateDemployeeId(), CustomerConstants.rightSourceCard.getValue(), item.getCustomerCardId(), item.getOrderSubId(), customerCard.getCardCode(), businessOrder.getPayType(), businessOrder.getOrdernum());
        }
    }
}
